package com.senyint.imsdk.util;

import java.io.UnsupportedEncodingException;

/**
 * 编码工具
 *
 */
public final class EncodeUtil {
	private static final String CHARSET = "UTF-8";

	/**
	 * 16进制转换整型
	 * 
	 * @param val
	 * @return
	 */
	public static Integer hexstring2int(String val) {
		return Integer.valueOf(val, 16);
	}

	/**
	 * 整型转换为16进制
	 * 
	 * @param val
	 * @return
	 */
	public static String int2hexstring(int val) {
		String hex = Integer.toHexString(val) ;
		if(hex.length()<2){
			return "0"+hex;
		}
		return Integer.toHexString(val);
	}

	/**
	 * 整型转换为16进制，且补充高位<br>
	 * 
	 * @param val
	 * @param size
	 *            16进制总位数
	 * @return
	 */
	public static String int2hexstring(int val, int size) {
		return fixHexStringOffset(Integer.toHexString(val), size);
	}

	/**
	 * char转换byte
	 * 
	 * @param c
	 * @return
	 */
	public static byte[] char2bytes(char c) {
		byte[] b = new byte[2];
		b[0] = (byte) ((c & 0xFF00) >> 8);
		b[1] = (byte) (c & 0xFF);
		return b;
	}

	/**
	 * byte转换char
	 * 
	 * @param b
	 *            2位数组byte
	 * @return 结果char
	 */
	public static char bytes2char(byte[] b) {
		char c = (char) (((b[0] & 0xFF) << 8) | (b[1] & 0xFF));
		return c;
	}

	/**
	 * 
	 * @param src
	 * @param size
	 *            高位补充
	 * @return
	 */
	public static String bytes2hexstring(byte[] src, int size) {
		return fixHexStringOffset(bytes2hexstring(src), size);
	}

	/**
	 * 字节数组转换为16进制字符串
	 * 
	 * @param src
	 * @return
	 */
	public static String bytes2hexstring(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}

	/**
	 * 指定字节数组部分转换成相应16进制字符串
	 * 
	 * @param src
	 *            待处理的完整byte数组
	 * @param start
	 *            数组起始坐标
	 * @param size
	 * 
	 * @return
	 */
	public static String bytes2hexstring(byte[] src, int start, int size) {
		return bytes2hexstring(getChildArray(src, start, size));
	}

	public static byte[] getChildArray(byte[] src, int start, int size) {
		if (src == null || src.length <= 0 || size <= 0) {
			return null;
		}
		byte[] bytes = new byte[size];
		for (int i = 0; i < size; i++) {
			bytes[i] = src[start + i];
		}
		return bytes;
	}

	/**
	 * 16进制字符串转换为字节数组
	 * 
	 * @param hexString
	 * @return
	 */
	public static byte[] hexstring2bytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (char2byte(hexChars[pos]) << 4 | char2byte(hexChars[pos + 1]));
		}

		return d;
	}

	/**
	 * char转换为字节
	 * 
	 * @param c
	 * @return
	 */
	private static byte char2byte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 字节转换为2进制bit
	 * 
	 * @param b
	 * @return
	 */
	public static String byte2bitstring(byte b) {
		return "" + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
				+ (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
				+ (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
				+ (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
	}

	/**
	 * 2进制bit字符串转化为字节
	 * 
	 * @param byteStr
	 * @return
	 */
	public static byte bit2byte(String byteStr) {
		int re, len;
		if (null == byteStr) {
			return 0;
		}
		len = byteStr.length();
		if (len != 4 && len != 8) {
			return 0;
		}
		if (len == 8) {// 8 bit处理
			if (byteStr.charAt(0) == '0') {// 正数
				re = Integer.parseInt(byteStr, 2);
			} else {// 负数
				re = Integer.parseInt(byteStr, 2) - 256;
			}
		} else {// 4 bit处理
			re = Integer.parseInt(byteStr, 2);
		}
		return (byte) re;
	}

	/**
	 * @param b
	 * @return
	 */
	public static byte[] byte2bitArray(byte b) {
		byte[] array = new byte[8];
		for (int i = 7; i >= 0; i--) {
			array[i] = (byte) (b & 1);
			b = (byte) (b >> 1);
		}
		return array;
	}

	public static void main(String[] args) {
		// System.out.println(EncodeUtil.bytes2int(new byte[]{1,68}));
		byte[] bina = byte2bitArray((byte) 30);
		System.out.println(bina);
		System.out.println(bit2int("0000000000101101"));

		byte[] bb = new byte[] { 0, 2, -56, -105, -10 };
		String terminalMobile = EncodeUtil.bytes2hexstring(bb);// String.valueOf(EncodeUtil.bytesToLong(data,
																// 11, 5));
		terminalMobile = "" + EncodeUtil.hexstring2long(terminalMobile);
		System.out.println(bina);

		long lld = EncodeUtil.bytes2long(bb);
		System.out.println(lld);

	}

	/**
	 * 整形转换为字节数组
	 * 
	 * @param i
	 * @return
	 */
	public static byte[] int2byteArray(int i) {
		return int2byteArray(i, 4);
	}

	/**
	 * byte数组转为整型<br>
	 * 
	 * @param iSource
	 * @param iArrayLen
	 *            默认4位
	 * @return
	 */
	public static byte[] int2byteArray(int iSource, int iArrayLen) {
		byte[] bLocalArr = new byte[iArrayLen];
		for (int i = 0; (i < 4) && (i < iArrayLen); i++) {
			bLocalArr[i] = (byte) (iSource >> 8 * i & 0xFF);
		}
		return bLocalArr;
	}

	/**
	 * // * @deprecated // * @param b // * @param offset // * @return //
	 */
	// public static int byteArrayToInt(byte[] b, int offset) {
	// int value = 0;
	// for (int i = 0; i < 4; i++) {
	// int shift = (4 - 1 - i) * 8;
	// value += (b[i + offset] & 0x000000FF) << shift;// 往高位游
	// }
	// return value;
	// }

	/**
	 * byte[]->int 大端模式
	 * 
	 * @param bytes
	 * @param start
	 *            开始
	 * @param length
	 *            长度
	 * @return
	 */

	public static int bytes2int(byte[] bytes, int start, int length) {
		return bytes2int(bytes, start, length, true);
	}

	public static int bytes2intSamll(byte[] bytes, int start, int length) {
		return bytes2int(bytes, start, length, false);
	}

	private static int bytes2int(byte[] bytes, int start, int length,
			boolean isBig) {
		if (1 > length || length > 4) {
			throw new RuntimeException(" int bytes length is 1-4:" + length);
		}
		byte[] bytesSub = getChildArray(bytes, start, length);
		int mask = 0xff;
		int temp = 0;
		int n = 0;
		for (int i = 0; i < bytesSub.length; i++) {
			n <<= 8;
			if (isBig) {// big
				temp = bytesSub[i] & mask;
			} else {// small
				temp = bytesSub[bytesSub.length - 1 - i] & mask;
			}
			n |= temp;
		}
		return n;
	}

	/**
	 * byte[]->long
	 * 
	 * @param bytesSub
	 * @param start
	 * @param length
	 * @return
	 */
	public static long bytes2long(byte[] bytes) {
		int mask = 0xff;
		int temp = 0;
		long n = 0;
		for (int i = 0; i < bytes.length; i++) {
			n <<= 8;
			temp = bytes[i] & mask;
			n |= temp;
		}
		return n;
	}

	public static long bytes2long(byte[] bytes, int start, int length) {
		return bytes2long(getChildArray(bytes, start, length));
	}

	/**
	 * int ->byte[]
	 * 
	 * @param a
	 * @param leng
	 * @return
	 */
	public static byte[] int2bytesBig(int a, int leng) {
		if (leng > 4 && leng < 1) {
			throw new RuntimeException(
					"int to bytes length must be 1-4,length is" + leng);
		}
		int byteLeng = 4;
		byte[] result = new byte[byteLeng];
		// result[0] = (byte)((a >> 24) & 0xFF);
		// 必须把我们要的值弄到最低位去，有人说不移位这样做也可以， result[0] = (byte)(i & 0xFF000000);
		// ，这样虽然把第一个字节取出来了，但是若直接转换为byte类型，会超出byte的界限，出现error。再提下数//之间转换的原则（不管两种类型的字节大小是否一样，原则是不改变值，内存内容可能会变，比如int转为//float肯定会变）所以此时的int转为byte会越界，只有int的前三个字节都为0的时候转byte才不会越界。虽//然
		// result[0] = (byte)(i & 0xFF000000); 这样不行，但是我们可以这样 result[0] =
		// (byte)((i & //0xFF000000) >>24);
		// result[1] = (byte)((a >> 16) & 0xFF);
		// result[2] = (byte)((a >> 8) & 0xFF);
		// result[3] = (byte)(a & 0xFF);
		for (int i = 0; i < byteLeng; i++) {
			result[i] = (byte) ((a >> (byteLeng - 1 - i) * 8) & 0xFF);
		}
		if (leng == 4) {
			return result;
		} else {
			return getChildArray(result, result.length - leng, leng);
		}
	}

	/**
	 * long ->byte[]
	 * 
	 * @param a
	 * @param leng
	 * @return
	 */
	public static byte[] long2bytesBig(long a, int leng) {
		if (leng > 8 && leng < 1) {
			throw new RuntimeException(
					"int to bytes length must be 1-8,length is" + leng);
		}
		int byteLeng = 8;
		byte[] result = new byte[byteLeng];
		for (int i = 0; i < byteLeng; i++) {
			result[i] = (byte) ((a >> (byteLeng - 1 - i) * 8) & 0xFF);
		}
		if (leng == 8) {
			return result;
		} else {
			return getChildArray(result, result.length - leng, leng);
		}
	}

	/**
	 * 弥补16进制高位数据
	 * 
	 * @param source
	 *            元数据
	 * @param offset
	 *            完整数
	 * @return
	 */
	public static String fixHexStringOffset(String source, int size) {
		if (size % 2 != 0) {
			// TODO 错误,非法16进制数据,返回元数据
			return source;
		}

		if (source.length() < size) {
			int offset = size - source.length();
			for (int i = 0; i < offset; i++) {
				source = "0" + source;
			}
		} else if (source.length() > size) {
			int offset = source.length() - size;
			source = source.substring(offset, source.length());
		}
		return source;
	}

	// /**
	// * 16进制字符串转换为Long整型数据
	// * @param val
	// * @return
	// */
	// public static long hex2longstring(String val) {
	// StringBuilder buf = new StringBuilder();
	// byte[] bytes = hexStringToBytes(val);
	//
	// for(int i=0;i<bytes.length;i++){
	// buf.append(String.valueOf(bytes[i])) ;
	// }
	//
	// return Long.parseLong(buf.toString()) ;
	// }

	/**
	 * 将文本字符串转换为16进制字符<br>
	 * 默认编码utf-8
	 * 
	 * @param temId
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String string2hexstring(String temId) {
		return string2hexstring(CHARSET, temId);
	}

	/**
	 * 将文本字符串转换为16进制字符<br>
	 * 根据编码获取字符串对应的byte，然后转换为16进制字符串
	 * 
	 * @param val
	 * @param encoding
	 *            指定编码
	 * @return @
	 */
	public static String string2hexstring(String encoding, String temId) {
		try {
			return bytes2hexstring(temId.getBytes(encoding));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 长整型转换为16进制，且补充高位<br>
	 * 
	 * @param val
	 * @param size
	 *            16进制总位数
	 * @return
	 */
	public static String long2hexstring(long val, int size) {
		return fixHexStringOffset(Long.toHexString(val), size);
	}

	/**
	 * 10进制字符串转换为16进制，且补充高位<br>
	 * 
	 * @param val
	 * @param size
	 *            16进制总位数
	 * @return
	 */
	public static String string2hexstring(String val, int size) {
		return fixHexStringOffset(string2hexstring(val), size);
	}

	/**
	 * 将16进制数据转换为文本字符串<br>
	 * 默认编码utf-8
	 * 
	 * @param val
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String hexstring2string(String val) {
		if(val == null){
			return null;
		}
		return hexstring2string(val, CHARSET);
	}

	/**
	 * 将16进制数据转换为文本字符串<br>
	 * 将16进制数据转换为byte[]，然后根据编码生成字符串
	 * 
	 * @param val
	 * @param encoding
	 *            指定编码
	 * @return @
	 */
	public static String hexstring2string(String val, String encoding) {
		try {
			return new String(hexstring2bytes(val), encoding);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 字节数组转换字符串<br>
	 * 默认编码UTF-8
	 * 
	 * @param bytes
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String bytes2string(byte[] bytes) {
		try {
			return new String(bytes, CHARSET);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 字节数组转换字符串
	 * 
	 * @param bytes
	 * @param encoding
	 *            指定编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String bytes2string(byte[] bytes, String encoding) {
		try {
			return new String(bytes, encoding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取byte子数组，并且转换成string <br>
	 * 默认编码UTF-8
	 * 
	 * @param src
	 *            数据源
	 * @param start
	 *            起始序号
	 * @param size
	 *            数据大小
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String bytes2string(byte[] src, int start, int size) {
		return bytes2string(src, start, size, CHARSET);
	}

	/**
	 * 获取byte子数组，并且转换成string
	 * 
	 * @param src
	 * @param start
	 * @param size
	 * @param encoding
	 *            指定编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String bytes2string(byte[] src, int start, int size,
			String encoding) {
		byte[] bytes = getChildArray(src, start, size);
		return bytes2string(bytes, encoding);
	}

	/**
	 * 字节数组转换int值<br>
	 * 
	 * @param byteArr
	 * @return
	 */
	public static int bytes2int(byte[] byteArr) {
		int rest = byteArr.length % 4;
		byte[] data = byteArr;
		if (rest > 0) {
			data = new byte[byteArr.length + rest];
			for (int i = 0; i < byteArr.length; i++) {
				data[i] = byteArr[i];
			}
		}
		int iOutcome = 0;
		byte bLoop;

		for (int i = 0; i < data.length; i++) {
			bLoop = data[i];
			iOutcome += (bLoop & 0xFF) << (8 * i);
		}
		return iOutcome;
	}

	/**
	 * 16进制数据转换为Long整型
	 * 
	 * @param hex
	 * @return
	 */
	public static Long hexstring2long(String hex) {
		return Long.parseLong(hex, 16);
	}

	public static int bit2int(String bits) {
		return Integer.parseInt(bits, 2);
	}
	
	public static String bcd2intString(String bits) {
		StringBuffer buf = new StringBuffer();
		for(int i=0;i<bits.length();i+=8){
			String bit = bits.substring(i,i+8);
			int hex = Integer.parseInt(bit, 2);
			if(hex < 10){
				buf.append("0"+hex);
			}else{
				buf.append(hex);
			}
			
//			System.out.println("bit:"+bit+",int:"+Integer.parseInt(bit, 2)+",hex:"+EncodeUtil.int2hexstring(Integer.parseInt(bit, 2)));
//			buf.append(EncodeUtil.int2hexstring(Integer.parseInt(bit, 2)));
		}
		return buf.toString();
	}

	public static String toBCD(String s) {
		StringBuffer bcd = new StringBuffer();
		for(int i=0;i<s.length();i++){
			int c = s.codePointAt(i);
			bcd.append(toBCD(c-48));
		}
		return bcd.toString() ;
	}
	
	public static String toBCD(int num) {
		String numStr = Integer.toString(num);
		/* B:每一个十进制数用BCD码表示，则相当于按照十六进制进行parse */
		Integer bcdObj = Integer.parseInt(numStr, 16);
		int bcdValue = bcdObj.intValue();
		String bcd = Integer.toBinaryString(bcdValue);
		int len = bcd.length();
		int mod = len / 4;
		if (len % 4 != 0) {
			mod = mod + 1;
		}
		if (len <= 4 * mod) {
			for (int j = 0; j < 4 * mod - len; j++) {
				bcd = "0" + bcd;
			}
		}
		return bcd;
	}

}
